/***********************************************************
 * author: wuzhong
 * create: 2022-09-05
 * email：419479707@qq.com
 * source:
 * board:esp8266 core for arduino v3.0.2
 ***********************************************************/

#include "Helper.h"
#ifndef APSSID
#define APSSID "dht"
#define APPSK  "11111111"
#endif

WiFiClient wifiClient;
PubSubClient mqttClient;
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;

//==================================== 这是需要配置的项 ===============================
/* Set these to your desired credentials. */
const char *aPSsid = APSSID;
const char *aPPassword = APPSK;

// Wifi配置
int wifiOpen = 0;
char *wifiSsid = "wps";
char *wifiPwd = "11111111";

// Mqtt配置
int mqttOpen = 0;
char *mqttHost = "192.168.2.88";
int mqttPort = 1883;
char *deviceIdentification = "bihua_t_h";
char *deviceTopic = "/v1/devices/bihua_t_h/datas";
char *mqttUserName = "bihua";
char *mqttUserPassport = "bihua";

void createAPAndWebServer(){
  printMsg("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(aPSsid, aPPassword);

  IPAddress myIP = WiFi.softAPIP();
  printMsg("AP IP address: ");
  Serial.println(myIP);
  server.on("/", handle_OnConnect);
  server.on("/dhtConfig", handle_DhtConfig);
  server.onNotFound(handle_NotFound);

  //网页更新固件
  httpUpdater.setup(&server); 
    
  server.begin();
  printMsg("HTTP server started");
}
void handle_OnConnect() {
  server.send(200, "text/html", SendHTML());
}
//处理LED控制请求的函数'handleLED'
void handle_DhtConfig() {                          
  if (server.method() != HTTP_POST) {
    server.send(405, "text/plain", "Method Not Allowed");
  } else {
    String message = "POST form was:\n";
    const char *ssid;
    const char *pwd;
    const char *host;
    int port;
    const char *identification;
    const char *userName;
    const char *userPassport;
    bool wifiOpen = 1;        
    bool mqttFlag = 1;
    for (uint8_t i = 0; i < server.args(); i++) {
      message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
      if(server.argName(i) == "ssid"){
        if(server.arg(i).isEmpty()){
          printMsg("ssid is null...");
          message += " ssid is null \n";
          wifiOpen = 0;
        }else{
          ssid = server.arg(i).c_str();
        }
      }else if(server.argName(i) == "pwd"){
        if(server.arg(i).isEmpty()){
          printMsg("pwd is null...");
          message += " pwd is null \n";
          wifiOpen = 0;
        }else{
          pwd = server.arg(i).c_str();
        }
      }else if(server.argName(i) == "host"){
        if(server.arg(i).isEmpty()){
          printMsg("host is null...");
          message += " host is null \n";
          mqttFlag = 0;
        }else{
          host = server.arg(i).c_str();
        }
      }else if(server.argName(i) == "port"){
        if(server.arg(i).isEmpty()){
          message += " port is null\n";
          printMsg("port is null...");
          mqttFlag = 0;
        }else{
          port = atoi(server.arg(i).c_str());
        }
      }else if(server.argName(i) == "identification"){
        if(server.arg(i).isEmpty()){
          message += " identification is null\n";
          printMsg("identification is null...");
          mqttFlag = 0;
        }else{
          identification = server.arg(i).c_str();
        }
      }else if(server.argName(i) == "userName"){
        if(server.arg(i).isEmpty()){
          message += " userName is null\n";
          printMsg("userName is null...");
          mqttFlag = 0;
        }else{
          userName = server.arg(i).c_str();
        }        
      }else if(server.argName(i) == "userPassport"){
        if(server.arg(i).isEmpty()){
          message += " userPassport is null\n";
          printMsg("userPassport is null...");
          mqttFlag = 0;
        }else{
          userPassport = server.arg(i).c_str();
        }       
      }             
    }
    if (strcmp(identification, deviceIdentification)!= 0) {
        message += " identification is wrong\n";
        printMsg("identification is wrong...");
        mqttFlag = 0;
    }
    if(wifiOpen){
      if (WiFi.status() == WL_CONNECTED){
         message += " WIFI successfully connected, no need to reconnect!\n";
      }else{
        String result = connectWifi(ssid, pwd);
        message += " " + result  + "\n";
      }
    }
    if(mqttFlag){
      if (mqttClient.connected()){
        message += " Mqtt successfully connected, no need to reconnect!\n";
      }else{
        String result = connectMqtt(host, port, identification, userName, userPassport);
        message += " " + result  + "\n";
      }   
    }
    
    server.send(200, "text/plain", message);
    
  }  
}
void handle_NotFound() {
  server.send(404, "text/plain", "Not found");
}

String SendHTML() {
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr += "<head> <meta name=\"viewport\" content=\"width=device-width,  initial-scale=1.0, user-scalable=no\">\n";
  ptr += "<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
  ptr += "<meta charset=\"UTF-8\">\n";
  ptr += "<title>碧华温湿度监控设备上线配置</title>\n";
  ptr += "<style>\n";
  ptr += "body{margin-top: 50px;}\n";
  ptr += "h1 {margin: 50px auto 30px;}\n";
  ptr += ".form-item{margin:10px 0 5px 12px;}\n";
  ptr += ".form-item label{width:100px;display:inline-block;}\n";
  ptr += ".form-item input,.form-item select{height:25px;line-height:25px;width:220px;border-radius:3px;border:1px solid #e2e2e2;}\n";
  ptr += ".form-item input[type=\"submit\"]{width:150px;height:30px;line-height:30px;}\n";
  ptr += ".data{padding: 10px;}\n";
  ptr += "</style>\n";
  ptr += "</head>\n";
  ptr += "<body>\n";
  ptr += "<div id=\"formpage\">\n";
    ptr += "<h1>碧华温湿度监控设备上线配置</h1>\n";
    ptr += "<div class=\"data\">\n";
    ptr += "</div>\n";
        
    ptr += "<form class=\"form\" action=\"/dhtConfig\" enctype=\"application/x-www-form-urlencoded\"  method=\"POST\">\n";
    ptr += "<div class=\"form-item\">\n";
      ptr += "<label for=\"ssid\">\n";
      ptr += "WIFI名称:<input type=\"text\" name=\"ssid\"  id=\"ssid\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";
      ptr += "<label for=\"pwd\">\n";
      ptr += "WIFI密码:<input type=\"text\" name=\"pwd\"  id=\"pwd\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";      
    ptr += "<div class=\"data\">\n";
    ptr += "</div>\n";
        
    ptr += "<div class=\"form-item\">\n";
      ptr += "<label for=\"host\">\n";
      ptr += "服务器地址:<input type=\"text\" name=\"host\"  id=\"host\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";       
      ptr += "<label for=\"port\">\n";
      ptr += "服务器端口:<input type=\"text\" name=\"port\"  id=\"port\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";         
      ptr += "<label for=\"identification\">\n";
      ptr += "设备的标识:<input type=\"text\" name=\"identification\"  id=\"identification\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";
      ptr += "<label for=\"userName\">\n";
      ptr += "服务器账号:<input type=\"text\" name=\"userName\"  id=\"userName\">\n";
      ptr += "</label><br/>\n";
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";           
      ptr += "<label for=\"userPassport\">\n";
      ptr += "服务器密码:<input type=\"text\" name=\"userPassport\"  id=\"userPassport\">\n";
      ptr += "</label><br/>\n";  
    ptr += "</div>\n";  
    ptr += "<div class=\"form-item\">\n";              
      ptr += "<input type=\"submit\" value=\"DHT配置\"></form>\n";
    ptr += "</div>\n";       
  ptr += "</div>\n";
  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}
// 连接wifi
void connectWifi()
{
  printMsg("连接WiFi ");
  Serial.print(wifiSsid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(wifiSsid, wifiPwd);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  printMsg("WiFi连接成功");
  printMsg("IP地址: ");
  Serial.print(WiFi.localIP());
}

String connectWifi(const char *ssid, const char *pwd)
{
  printMsg("连接WiFi ");
  Serial.print(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pwd);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  strcpy(wifiSsid, ssid);
  strcpy(wifiPwd, pwd);
  wifiOpen = 1;
  printMsg("WiFi连接成功");
  printMsg("IP地址: ");
  Serial.print(WiFi.localIP());
  return "WIFI connection successful";
}

// 连接mqtt
void connectMqtt()
{
  printMsg("连接Mqtt服务器...");
  mqttClient.setClient(wifiClient);
  mqttClient.setServer(mqttHost, mqttPort);
  mqttClient.setBufferSize(1024);
  mqttClient.setKeepAlive(10);
  bool connectResult = mqttClient.connect(deviceIdentification, mqttUserName, mqttUserPassport);
  if (connectResult)
  {
    printMsg("Mqtt连接成功 ");
    Serial.print(mqttHost);
  }
  else
  {
    printMsg("连接失败, rc=");
    Serial.print(mqttClient.state());
  }
}

// 连接mqtt
String connectMqtt(const char *host, int port, const char *identification, const char *userName, const char *userPassport)
{
  printMsg("连接Mqtt服务器...");
  mqttClient.setClient(wifiClient);
  mqttClient.setServer(host, port);
  mqttClient.setBufferSize(1024);
  mqttClient.setKeepAlive(10);
  bool connectResult = mqttClient.connect(identification, userName, userPassport);
  if (connectResult)
  {
    printMsg("Mqtt连接成功 ");
    strcpy(mqttHost, host);
    mqttPort = port;
    strcpy(deviceIdentification, identification);
    strcpy(mqttUserName, userName);
    strcpy(mqttUserPassport, userPassport);
    mqttOpen = 1;
    Serial.print(host);
    return "Mqtt connection successful";
  }
  else
  {
    printMsg("连接失败, rc=");
    Serial.print(mqttClient.state());
    return "Mqtt connection failed, rc="+mqttClient.state();
  }
}
//打印提示信息
void printMsg(String msg)
{
  Serial.print("\r\n[");
  Serial.print(millis());
  Serial.print("ms]");
  Serial.print(msg);
}

// 控制指示灯闪烁
void blink()
{
  printMsg("指示灯闪烁...");
  pinMode(LED_BUILTIN, OUTPUT);
  for (int i = 0; i < 2; i++)
  {
    digitalWrite(LED_BUILTIN, LOW);
    delay(200);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(200);
  }
}
